home *** CD-ROM | disk | FTP | other *** search
- .286
- ;================================================
- ; Returns square root of real
- ;
- ;------------------------------------------------
- ; Newton-Raphson approximation method.
- ;
- ; x[i+1] = 0.5( c/x[i] + x[i] )
- ;
- ; if c = 25 and seed x[i] = 4
- ; 1st iteration = 0.5( 25/4 + 4 ) = 5.125
- ; 2nd iteration = 0.5( 25/5.125 + 5.125) = 5.0015
- ;
- ; Convergence ONLY IF suitable seed is chosen.
- ;------------------------------------------------
- cseg segment word public 'code'
- assume cs:cseg,ss:cseg
- assume ds:cseg,es:cseg
-
- include math.inc
-
- ftsqrt proc near real:NPR10
- local value:REAL10, seed:REAL10, square:REAL10
-
- pusha
- mov si, real ;
- and word ptr [si]+8, 7fffh ; positive only
- lea di, seed ;
-
- invoke movx, di, si, 5 ; seed = real
- mov dx, word ptr [di]+6 ;
- and dx, 8000h ; DX bit15 = explicit 1^
- mov ax, word ptr [di]+8 ;
- mov bx, ax ;
- and bx, 8000h ; BX = sign
- and ax, 7fffh ; remove sign
- sub ax, 3fffh ; remove bias
-
- .IF (SWORD PTR ax > 0) ; if exponent > 0
- .IF (ax & 1) ; if exponent is ODD
- inc ax ;
- shr ax, 1 ;
- invoke rshx, di, 4 ;
- or word ptr [di]+6, dx ;
- .ELSE ; if exponent is EVEN
- shr ax, 1 ;
- .ENDIF
-
- .ELSEIF (SWORD PTR ax < 0) ; if exponent < 0
- neg ax ;
- .IF (ax & 1) ; if exponent is ODD
- inc ax ;
- shr ax, 1 ;
- invoke rshx, di, 4 ;
- or word ptr [di]+6, dx ;
- .ELSE ; if exponent is EVEN
- shr ax, 1 ;
- .ENDIF
- neg ax ;
-
- .ELSEIF (ax == 0) ;
- invoke rshx, di, 4 ;
- or word ptr [di]+6, dx ;
-
- .ENDIF ;
- add ax, 3fffh ; add bias
- or ax, bx ; add sign
- mov word ptr [di]+8, ax ;
- invoke ftnormal, di ;
- ;------------------------------------------------
- mov cx, 16 ; max 16 iterations
-
- .WHILE (cx)
- invoke movx, addr value, si, 5 ; value = real
- invoke ftdiv, addr value, di ; value /= seed
- invoke ftadd, addr value, di ; value += seed
- invoke ftdivi, addr value, +2 ; value /= 2
- invoke movx, di, addr value, 5 ; seed = value
-
- invoke movx, addr square, di, 5 ; square = seed
- invoke ftpower, addr square, 2 ; square = square**2
- invoke ftsub, addr square, si ; square -= real
-
- mov ax, word ptr square[8] ;
- or ax, word ptr square[6] ;
- or ax, word ptr square[4] ;
- or ax, word ptr square[2] ;
- .BREAK .IF (ax == 0) ; exit if 48-bit accuracy
- dec cx ;
- .ENDW
-
- invoke movx, si, di, 5 ; return result
- popa
-
- ret
- ftsqrt endp
-
- cseg ends
- end